package cn.wanho.config;

import cn.wanho.handler.*;
import cn.wanho.securityuser.UserDetailServiceImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.config.annotation.ObjectPostProcessor;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.security.web.session.SessionInformationExpiredStrategy;

import javax.annotation.Resource;

@Configuration
public class webSecurityConfig extends WebSecurityConfigurerAdapter {
    @Bean
    public MyCustomerPasswordEncoder myCustomerPasswordEncoder(){
        return new MyCustomerPasswordEncoder();
    }

    /**
     * 用户未登录时处理的bean
     * @return
     */
    @Bean
    public AuthenticationEntryPoint authenticationEntryPoint(){
        return new UserAuthenticationEntryPoint();
    }
    @Bean
    @Override
    public UserDetailsService userDetailsService(){
        return new UserDetailServiceImpl();
    }
    @Bean
    public AuthenticationSuccessHandler authenticationSuccessHandler(){
        return new UserAuthenticationSuccessHandler();
    }
    @Bean
    public AuthenticationFailureHandler authenticationFailureHandler(){
        return new UserAuthenticationFailureHandler();
    }
    @Bean
    public LogoutSuccessHandler logoutSuccessHandler(){
        return new UserLogoutSuccessHandler();
    }
    @Bean
    public SessionInformationExpiredStrategy sessionInformationExpiredStrategy(){
        return new UserSessionInformationExpiredStrategy();
    }
    @Resource
    private UserAccessDeniedHandler userAccessDeniedHandler;
    @Bean
    public AccessDecisionManager accessDecisionManager(){
        return new UserAccessDecisionManager();
    }
    @Bean
    public FilterInvocationSecurityMetadataSource securityMetadataSource(){
        return new UserFilterInvocationSecurityMetadatasource();
    }
@Resource
private UserAbstractSecurityInterceptor userAbstractSecurityInterceptor;
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and().csrf().disable();
            http.authorizeRequests()//授权配置
                .withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {
                    @Override
                    public <O extends FilterSecurityInterceptor> O postProcess(O object) {
                        object.setAccessDecisionManager(accessDecisionManager());
                        object.setSecurityMetadataSource(securityMetadataSource());
                        return object;
                    }
                })
                . and()
                .formLogin().permitAll()//允许所有用户登入
                    //登录成功处理逻辑
                .successHandler(authenticationSuccessHandler())
                    //登录失败处理逻辑
                .failureHandler(authenticationFailureHandler())
                .and().logout()//登出
                .permitAll()
                    //登出处理逻辑
                .logoutSuccessHandler(logoutSuccessHandler())
                .deleteCookies("JSESSIONID")
                    .and()
                    .exceptionHandling().accessDeniedHandler(userAccessDeniedHandler)
                    //匿名用户访问无权限资源的时候的异常处理
                .and().exceptionHandling().authenticationEntryPoint(authenticationEntryPoint())
                    .and()
                    .sessionManagement()
                    //同一账号最大登录数量
                    .maximumSessions(1)
                    //会话过期策略的处理bean
                    .expiredSessionStrategy(sessionInformationExpiredStrategy());

            http.addFilterBefore(userAbstractSecurityInterceptor,FilterSecurityInterceptor.class);
    }
}
